<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>组件通信</title>
    <script src="./vue.js"></script>
  </head>
  <body>
    <div id="app">
      <parent></parent>
    </div>
  </body>
</html>
<script>
  // 组件通信
  // 1. 父向子传值
  // 1.1 父亲 通过属性给子组件传值
  // 1.2 儿子：通过props接受值
  // 2. 子向父传值 可以理解为 父给子传递一个函数或发布订阅
  // 2.1 父亲 通过v-on传递  v-on:yy="callback"
  // 2.2 儿子：通过$emit('yy', 6666)调用父亲给我传递的函数并传递参数
  // 也可以通过发布订阅方式理解：
  // 父亲订阅公众号v-on:yy="callback" 父亲订阅和儿子发布一定要是同一个公众号
  // 儿子通过公众号发布消息$emit('yy', 6666) yy就好比公众号
  // 3. 非父子通信 事件总线 非父子包含兄弟但不局限兄弟
  // 3.1 创建一个事件总线
  var bus = new Vue()
  // 3.2 发布消息 通过bus发布
  // 3.3 接受消息 通过bus接受
  // 4. 跨代传值 provie inject
  // 4.1 祖代： 通过provide给后代写遗嘱
  // 4.2 后代： 通过inject接受
  // 5. $parent一层层找
  // 6. $root根组件
  // 7. $children
  // 需要注意5.6.7其实有点浪费 我只想获取数据 但是我们这几种方式我获取都是组件 大材小用
  // 8. $refs这种方式下次再讲
  // 定义组件
  Vue.component('parent', {
    template: `<div>
      <h2>parent组件</h2>
      <child></child>
    </div>`
  })
  Vue.component('child', {
    data () {
      return {
        sfq: '我是child的私房钱'
      }
    },
    template: `<div>
      <h2>child组件</h2>
      <son></son>
      </hr>
    </div>`
  })
  Vue.component('son', {
    data () {
      return {
        whfangzi: '武汉房子'
      }
    },
    template: `<div>
      <h2>son组件</h2>
      <button @click="getVmData">获取vm上的money</button>
    </div>`,
    methods: {
      getVmData () {
        // console.log(this.$parent.$parent.$parent) // 找父组件 父组件上的所有的属性我都可以获取到了
        console.log(this.$parent.$parent.$parent.money, 1111) // 找父组件 父组件上的所有的属性我都可以获取到了
        console.log(this.$root.money, 2222) // 找父组件 父组件上的所有的属性我都可以获取到了
      }
    },
  })
  var vm = new Vue({
    el: '#app',
    data: {
      money: '2个亿'
    },
    mounted() {
      // 时机无所谓 你在点击事件也可以
      // console.log(this.$children[0].$children[0].$children[0], 'vm组件mounted')
      console.log(this.$children[0].$children[0].$children[0].whfangzi, 'vm组件mounted')
    }
  })
</script>
